package com.naiterui.ehp.bs.agent.controller;

import com.naiterui.common.repository.page.PageParamVO;
import com.naiterui.common.repository.page.PageVO;
import com.naiterui.ehp.bp.constants.SwaggerTag;
import com.naiterui.ehp.bp.support.exception.BaseExceptionCodes;
import com.naiterui.ehp.bp.support.exception.BusinessException;
import com.naiterui.ehp.bp.support.security.SettingConfig;
import com.naiterui.ehp.bp.utils.encypt.RSAUtil;
import com.naiterui.ehp.bp.utils.lang.ConfigUtil;
import com.naiterui.ehp.bs.agent.po.AgentAuthPO;
import com.naiterui.ehp.bs.agent.service.IAgentService;
import com.naiterui.ehp.bs.agent.vo.AgentAuthInfoVO;
import com.naiterui.ehp.bs.agent.vo.AgentDetailVO;
import com.naiterui.ehp.bs.agent.vo.AgentItemVO;
import com.naiterui.ehp.bs.agent.vo.BaseInfoVO;
import com.naiterui.ehp.bs.agent.vo.UserVO;
import com.naiterui.ehp.bs.agent.websocket.WebsocketConstant;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yiren
 * @since 2022/2/10
 */
@Slf4j
@Api(tags = {SwaggerTag.AGENT + "用户相关接口"})
@AllArgsConstructor
@RestController
@RequestMapping("user")
public class AgentController {

    private final IAgentService agentService;

    @ApiOperation("获取公钥")
    @GetMapping("getPublicKey")
    public Map<String, String> getRSAPublicKey() throws Exception {
        String key = RSAUtil.getPublicKeyStr();
        Map<String, String> map = new HashMap<>();
        map.put("publicKey", key);
        return map;
    }

    @PostMapping("login")
    @ApiOperation("登录接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phoneNum", value = "手机号", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "password", value = "密码，公钥加密（当密码为空时验证码必填）", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "code", value = "验证码（当验证码为空时密码必填）", dataType = "string", paramType = "query"),
    })
    public UserVO login(String phoneNum, String password, String code) throws BusinessException {
        if (StringUtils.isEmpty(phoneNum) || StringUtils.isAllEmpty(code, password)){
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        UserVO login = agentService.login(phoneNum, password, code);
        //登录完成后，补充websocket相关配置
        login.setWebsocketHost(ConfigUtil.getString(WebsocketConstant.WEBSOCKET_HOST_CONFIGKEY));
        login.setHeartBeatRate(WebsocketConstant.HEART_BEAT_RATE);
        login.setHeartBeatSignal(WebsocketConstant.HEART_BEAT_SIGNAL);
        return login;
    }

    @PostMapping("resetPwd")
    @ApiOperation("修改密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phoneNum", value = "手机号", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "newPassword", value = "新密码，公钥加密", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "code", value = "验证码", dataType = "string", paramType = "query", required = true),
    })
    public void resetPwd(String phoneNum, String newPassword, String code) throws BusinessException {
        if (StringUtils.isAnyEmpty(phoneNum, newPassword, code)){
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        agentService.resetPwd(phoneNum, newPassword, code);
    }

    @PostMapping("resetPhone")
    @ApiOperation("修改手机号")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "newPhoneNum", value = "新手机号", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "code", value = "验证码", dataType = "string", paramType = "query", required = true),
    })
    public void resetPhone(@RequestHeader Long agentId, String newPhoneNum, String code) throws BusinessException {
        if (StringUtils.isAnyEmpty(newPhoneNum, code)){
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        agentService.resetPhone(agentId, newPhoneNum, code);
    }

    @PostMapping("resetHead")
    @ApiOperation("修改头像")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "headUrl", value = "头像地址", dataType = "string", paramType = "query", required = true),
    })
    public void resetHead(@RequestHeader Long agentId, String headUrl) throws BusinessException {
        if (StringUtils.isAnyEmpty(headUrl)){
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        agentService.resetHead(agentId, headUrl);
    }

    @GetMapping("sendCode")
    @ApiOperation("发送验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phoneNum", value = "手机号", dataType = "string", paramType = "query", required = true),
            @ApiImplicitParam(name = "type", value = "类型 (1:登录, 2:找回密码, 3:修改手机号)", dataType = "int", paramType = "query", required = true),
    })
    public void sendCode(String phoneNum, Integer type) throws BusinessException {
        if (type == null || StringUtils.isAnyEmpty(phoneNum)){
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        agentService.sendCode(phoneNum, type);
    }

    @GetMapping("auth/get")
    @ApiOperation("获取认证信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "agentId", value = "经纪人ID", dataType = "string", paramType = "query", required = true),
    })
    public AgentAuthInfoVO getAuth(Long agentId) throws BusinessException {
        if (agentId == null){
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        return agentService.getAuthInfo(agentId);
    }

    @PostMapping("auth/save")
    @ApiOperation("保存认证信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "agentId", value = "经纪人ID", dataType = "string", paramType = "query", required = true),
    })
    public void saveAuth(AgentAuthPO authPO) throws BusinessException {
        if (StringUtils.isAnyEmpty(authPO.getCardNo(), authPO.getAgentName())){
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        String cardNo = authPO.getCardNo();
        if (cardNo.length() != 18  && cardNo.length() != 15){
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR, "请提交真实的身份证号");
        }
        agentService.saveAuthInfo(authPO);
    }


    @GetMapping("logout")
    @ApiOperation("退出登录")
    public void logout(@RequestHeader(SettingConfig.AGENT_ID) Long agentId, String token) throws BusinessException {
        agentService.logout(agentId, token);
    }


    @GetMapping("baseInfo")
    @ApiOperation("查询经纪人基础信息")
    public BaseInfoVO baseInfo(@RequestHeader(SettingConfig.AGENT_ID) Long agentId) {

        return agentService.getBaseInfo(agentId);
    }

    @GetMapping("detail")
    @ApiOperation("根据ID查询经纪人详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "agentId", value = "经纪人ID", dataType = "string", paramType = "query", required = true),
    })
    public AgentDetailVO detail(Long agentId) throws BusinessException {

        return agentService.getDetail(agentId);
    }

    @GetMapping("list")
    @ApiOperation("查询经纪人列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "areaId", value = "省区ID", dataType = "long", paramType = "query", required = true),
    })
    public PageVO<AgentItemVO> list(PageParamVO pageParamVO, Long areaId) throws BusinessException {
        if (areaId == null) {
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR);
        }
        return agentService.findAgentPage(pageParamVO, areaId);
    }

    @ApiOperation(value = "APP端文件上传", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping("/upload/{type}")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "type", value = "文件类型(1:个人照片,2:认证照片)",
                    dataType = "int", paramType = "path", required = true),})
    public List<String> upload(@NotNull(message = "上传文件不能为null") MultipartFile file, Long agentId,
                                     @PathVariable int type) throws BusinessException {
        log.info("APP端文件上传 agentId:{}, type:{}, fileName: {}", agentId, type, file.getOriginalFilename());
        try {
            String url = agentService.uploadFile(type, file);
            return Arrays.asList(url);
        }catch (Exception e){
            log.error("文件保存失败", e);
            throw new BusinessException(BaseExceptionCodes.PARAM_ERROR, "文件保存失败");
        }

    }



}
